Introduction

library(ggplot2)

library(lattice)

library(latticeExtra)

library(ggpubr)

library(scatterplot3d)

library(gridExtra)

library(ggfortify)

##shiny::runGitHub("cardiomoon/ggplot2new")

One variable visualization


## Histogram in ggplot package
ggplot(data = diamonds, aes(price)) + geom_histogram()


## Histogram varied based on the cut of the diamonds (group)
ggplot(data = diamonds, aes(price, color = cut)) + geom_histogram()



## Densityplot in ggplot package
ggplot(data = diamonds, aes(price)) + geom_density()


## Densityplot varied based on the cut of the diamonds (group)
ggplot(data = diamonds, aes(price, color = cut)) + geom_density()


## Frequency plot in ggplot package
ggplot(data = diamonds, aes(price)) + geom_freqpoly()


## Frequency plot is visualized based on the cut (group)
ggplot(data = diamonds, aes(price, color = cut)) + geom_freqpoly()



## Histogram in lattice package. Price is visualized based on the cut of the diamonds. 
histogram(~ price | factor(cut), data = diamonds)


## Histogram using ggpubr package. Price is visualized based on cut of the diamonds.
gghistogram(diamonds, x = "price",
            add = "mean", rug = TRUE, color = "cut",
            palette = c("red", "blue", "green", "brown", "violet"))
Using `bins = 30` by default. Pick better value with the argument `bins`.

## Densityplots using ggpubr package. Price is visualized based on cut of the diamonds.
ggdensity(diamonds, x = "price",
          add = "mean", rug = TRUE,
          color = "cut",
          palette = c("red", "blue", "green", "brown", "violet"))

NA
NA
NA
NA

R Code for Discrete One Variable Visualization

ggplot(data = world, aes(dem_level4, fill = gdp_cap3)) + geom_bar() 


       
ggplot(data = world, aes(dem_level4, fill = regime_type3)) + geom_bar()


## Facet Grid attachment to separate based on different regions
ggplot(data = world, aes(dem_level4, fill = regime_type3)) + geom_bar() + facet_grid(regionun ~.)

R Code for Two-variable visualization

## Discrete variable (X) and continous variable (Y)
## Boxplot Visualization. Gini Coefficient (inequality) (y-variable) visualized based on regime types (x-variable). 
ggplot(data = world, aes(x = regime_type3, y = gini10, color = oecd)) + geom_boxplot() 


ggplot(data = world, aes(x = dem_level4, y =  gini10, color = oecd)) + geom_boxplot() + coord_flip()



bwplot(factor(dem_level4) ~ gini10 , data = world, xlab = "Gini Coefficient", col = "green", fill  = "blue")



## Using the ggpubr package. 
ggbarplot(data = world, x =  "dem_level4", y = "gini10", fill = "regime_type3", xlab = "Democracy Level", ylab = "Gini Coefficient", short.panel.labs= T)




## Continuous variables on both axes. Levels of gini-coefficient (y) is visualized based on democracy score (x)

ggplot(data = world, aes(x = dem_score14, y = gini10)) + geom_point()  


ggplot(data = world, aes(x = dem_score14, y = gini10, color = gdp_cap3)) + geom_point() 


ggplot(data = world , aes(x = dem_score14, y = gini10, color = gdp_cap3)) + geom_point() + facet_wrap(~regionun)


## using Lattice package 
xyplot(gini10~dem_score14 | regime_type3 , data = world, 
       type = "h", xlab = "Democracy Levels")



## Discrete variable (X) and Discrete variable (Y). Here regime type is visualized with GDP per capita. 
ggplot(data = world, aes(x = dem_level4 , y = gdp_cap3, color = regime_type3)) + geom_count()  

R Code for Correlation Relationships

##. Correlation of numerical variables
corr = cor(diamonds[, c(1, 5:7)])
ggcorrplot(corr = corr)


## using GGally package. The Bush approval ratings is used to visualize the possible correlations. 
ggpairs(approval, columns = 7:11, ggplot2::aes(color=factor(X11.Sep)))

##. R Code for Regression Relationships

##using ggplot package for regression line fit
ggplot(data = world, aes(x = dem_score14, y = gini10 )) + geom_point(na.rm = T) + geom_smooth(method = "lm", na.rm = T)  


##using ggplot package for regression line fit (loess method)
ggplot(data = world, aes(x = dem_score14, y = gini10)) + geom_point(na.rm = T) + geom_smooth(method = "loess", na.rm = T) 


##using quantile regression estimation
ggplot(data = world, aes(x = dem_score14, y = gini10)) +geom_point(na.rm = T) + geom_quantile(na.rm = T)

Regression diagnostics using ggpubr and ggfortify

## Using ggpubr package
ggscatter(data = world, x = "dem_score14", y = "gini10",
   color = "black", shape = 21, size = 3, # Points color, shape and size
   add = "reg.line",  # Add regressin line
   add.params = list(color = "blue", fill = "lightgray"), # Customize reg. line
   conf.int = TRUE, # Add confidence interval
   cor.coef = TRUE, # Add correlation coefficient. see ?stat_cor
   cor.coeff.args = list(method = "pearson", label.x = 3, label.sep = "\n")
   )


##using ggeffects, ggfortify, and performance package to estimate and diagnosize the linearmodels
##Model.1: predicting and diagonizing the generalized linear model
m1 = lm(approve~gasprice + unemploy + katrina + lrgasprice, data = approval)
autoplot(m1, which = 1:6, ncol = 3, label.size = 3)



##Model.2: predicting and diagonizing the generalized linear model with addition of iraq invasion variable
m2 = lm(approve~gasprice + unemploy + katrina + lrgasprice + iraqinvade, data = approval)
autoplot(m2, which = 1:6, ncol = 3, label.size = 3)


##Model.3: predicting and diagonizing the generalized linear model with control variables
m3 = lm(approve~gasprice + unemploy + katrina + lrgasprice + iraqinvade + lcpifood + X11.Sep, data = approval)
autoplot(m3, which = 1:6, ncol = 3, label.size = 3)


## Coefficient estimates for various models
g1 = ggcoef(m1, vline_color = "green", sort = "ascending", exclude_intercept = T)
g2 = ggcoef(m2, vline_color = "blue", sort = "ascending", exclude_intercept = T)
g3 = ggcoef(m3, vline_color = "red", sort = "ascending", exclude_intercept = T)

grid.arrange(g1, g2, g3, nrow=3)

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIHBkZl9kb2N1bWVudDogCiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCiMjIEludHJvZHVjdGlvbiAKCmBgYHtyICBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKCmxpYnJhcnkobGF0dGljZSkKCmxpYnJhcnkobGF0dGljZUV4dHJhKQoKbGlicmFyeShnZ3B1YnIpCgpsaWJyYXJ5KHNjYXR0ZXJwbG90M2QpCgpsaWJyYXJ5KGdyaWRFeHRyYSkKCmxpYnJhcnkoZ2dmb3J0aWZ5KQoKIyNzaGlueTo6cnVuR2l0SHViKCJjYXJkaW9tb29uL2dncGxvdDJuZXciKQpgYGAKCgpgYGB7cn0KCmxpYnJhcnkoZ2dtb3NhaWMpCgpsaWJyYXJ5KGdnZWZmZWN0cykKCmxpYnJhcnkoR0dhbGx5KQoKbGlicmFyeShnZ2NvcnJwbG90KQoKbGlicmFyeShwb2xpc2NpZGF0YSkKCmxpYnJhcnkod29vbGRyaWRnZSkKCmxpYnJhcnkoZWFzeXN0YXRzKQoKYGBgCgoKIyMgT25lIHZhcmlhYmxlIHZpc3VhbGl6YXRpb24gCmBgYHtyIHBsb3RzLCBlY2hvPVRSVUUsIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1UUlVFfQoKIyMgSGlzdG9ncmFtIGluIGdncGxvdCBwYWNrYWdlCmdncGxvdChkYXRhID0gZGlhbW9uZHMsIGFlcyhwcmljZSkpICsgZ2VvbV9oaXN0b2dyYW0oKQoKIyMgSGlzdG9ncmFtIHZhcmllZCBiYXNlZCBvbiB0aGUgY3V0IG9mIHRoZSBkaWFtb25kcyAoZ3JvdXApCmdncGxvdChkYXRhID0gZGlhbW9uZHMsIGFlcyhwcmljZSwgY29sb3IgPSBjdXQpKSArIGdlb21faGlzdG9ncmFtKCkKCgojIyBEZW5zaXR5cGxvdCBpbiBnZ3Bsb3QgcGFja2FnZQpnZ3Bsb3QoZGF0YSA9IGRpYW1vbmRzLCBhZXMocHJpY2UpKSArIGdlb21fZGVuc2l0eSgpCgojIyBEZW5zaXR5cGxvdCB2YXJpZWQgYmFzZWQgb24gdGhlIGN1dCBvZiB0aGUgZGlhbW9uZHMgKGdyb3VwKQpnZ3Bsb3QoZGF0YSA9IGRpYW1vbmRzLCBhZXMocHJpY2UsIGNvbG9yID0gY3V0KSkgKyBnZW9tX2RlbnNpdHkoKQoKIyMgRnJlcXVlbmN5IHBsb3QgaW4gZ2dwbG90IHBhY2thZ2UKZ2dwbG90KGRhdGEgPSBkaWFtb25kcywgYWVzKHByaWNlKSkgKyBnZW9tX2ZyZXFwb2x5KCkKCiMjIEZyZXF1ZW5jeSBwbG90IGlzIHZpc3VhbGl6ZWQgYmFzZWQgb24gdGhlIGN1dCAoZ3JvdXApCmdncGxvdChkYXRhID0gZGlhbW9uZHMsIGFlcyhwcmljZSwgY29sb3IgPSBjdXQpKSArIGdlb21fZnJlcXBvbHkoKQoKCiMjIEhpc3RvZ3JhbSBpbiBsYXR0aWNlIHBhY2thZ2UuIFByaWNlIGlzIHZpc3VhbGl6ZWQgYmFzZWQgb24gdGhlIGN1dCBvZiB0aGUgZGlhbW9uZHMuIApoaXN0b2dyYW0ofiBwcmljZSB8IGZhY3RvcihjdXQpLCBkYXRhID0gZGlhbW9uZHMpCgojIyBIaXN0b2dyYW0gdXNpbmcgZ2dwdWJyIHBhY2thZ2UuIFByaWNlIGlzIHZpc3VhbGl6ZWQgYmFzZWQgb24gY3V0IG9mIHRoZSBkaWFtb25kcy4KZ2doaXN0b2dyYW0oZGlhbW9uZHMsIHggPSAicHJpY2UiLAogICAgICAgICAgICBhZGQgPSAibWVhbiIsIHJ1ZyA9IFRSVUUsIGNvbG9yID0gImN1dCIsCiAgICAgICAgICAgIHBhbGV0dGUgPSBjKCJyZWQiLCAiYmx1ZSIsICJncmVlbiIsICJicm93biIsICJ2aW9sZXQiKSkKCiMjIERlbnNpdHlwbG90cyB1c2luZyBnZ3B1YnIgcGFja2FnZS4gUHJpY2UgaXMgdmlzdWFsaXplZCBiYXNlZCBvbiBjdXQgb2YgdGhlIGRpYW1vbmRzLgpnZ2RlbnNpdHkoZGlhbW9uZHMsIHggPSAicHJpY2UiLAogICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLAogICAgICAgICAgY29sb3IgPSAiY3V0IiwKICAgICAgICAgIHBhbGV0dGUgPSBjKCJyZWQiLCAiYmx1ZSIsICJncmVlbiIsICJicm93biIsICJ2aW9sZXQiKSkKCgoKCmBgYAoKIyMgUiBDb2RlIGZvciBEaXNjcmV0ZSBPbmUgVmFyaWFibGUgVmlzdWFsaXphdGlvbgoKYGBge3IgT25ldmFyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmdncGxvdChkYXRhID0gd29ybGQsIGFlcyhkZW1fbGV2ZWw0LCBmaWxsID0gZ2RwX2NhcDMpKSArIGdlb21fYmFyKCkgCgogICAgICAgCmdncGxvdChkYXRhID0gd29ybGQsIGFlcyhkZW1fbGV2ZWw0LCBmaWxsID0gcmVnaW1lX3R5cGUzKSkgKyBnZW9tX2JhcigpCgojIyBGYWNldCBHcmlkIGF0dGFjaG1lbnQgdG8gc2VwYXJhdGUgYmFzZWQgb24gZGlmZmVyZW50IHJlZ2lvbnMKZ2dwbG90KGRhdGEgPSB3b3JsZCwgYWVzKGRlbV9sZXZlbDQsIGZpbGwgPSByZWdpbWVfdHlwZTMpKSArIGdlb21fYmFyKCkgKyBmYWNldF9ncmlkKHJlZ2lvbnVuIH4uKQoKYGBgCgojIyBSIENvZGUgZm9yIFR3by12YXJpYWJsZSB2aXN1YWxpemF0aW9uIAoKYGBge3IgIFR3b3ZhciwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyBEaXNjcmV0ZSB2YXJpYWJsZSAoWCkgYW5kIGNvbnRpbm91cyB2YXJpYWJsZSAoWSkKIyMgQm94cGxvdCBWaXN1YWxpemF0aW9uLiBHaW5pIENvZWZmaWNpZW50IChpbmVxdWFsaXR5KSAoeS12YXJpYWJsZSkgdmlzdWFsaXplZCBiYXNlZCBvbiByZWdpbWUgdHlwZXMgKHgtdmFyaWFibGUpLiAKZ2dwbG90KGRhdGEgPSB3b3JsZCwgYWVzKHggPSByZWdpbWVfdHlwZTMsIHkgPSBnaW5pMTAsIGNvbG9yID0gb2VjZCkpICsgZ2VvbV9ib3hwbG90KCkgCgpnZ3Bsb3QoZGF0YSA9IHdvcmxkLCBhZXMoeCA9IGRlbV9sZXZlbDQsIHkgPSAgZ2luaTEwLCBjb2xvciA9IG9lY2QpKSArIGdlb21fYm94cGxvdCgpICsgY29vcmRfZmxpcCgpCgoKYndwbG90KGZhY3RvcihkZW1fbGV2ZWw0KSB+IGdpbmkxMCAsIGRhdGEgPSB3b3JsZCwgeGxhYiA9ICJHaW5pIENvZWZmaWNpZW50IiwgY29sID0gImdyZWVuIiwgZmlsbCAgPSAiYmx1ZSIpCgoKIyMgVXNpbmcgdGhlIGdncHViciBwYWNrYWdlLiAKZ2diYXJwbG90KGRhdGEgPSB3b3JsZCwgeCA9ICAiZGVtX2xldmVsNCIsIHkgPSAiZ2luaTEwIiwgZmlsbCA9ICJyZWdpbWVfdHlwZTMiLCB4bGFiID0gIkRlbW9jcmFjeSBMZXZlbCIsIHlsYWIgPSAiR2luaSBDb2VmZmljaWVudCIsIHNob3J0LnBhbmVsLmxhYnM9IFQpCgoKCiMjIENvbnRpbnVvdXMgdmFyaWFibGVzIG9uIGJvdGggYXhlcy4gTGV2ZWxzIG9mIGdpbmktY29lZmZpY2llbnQgKHkpIGlzIHZpc3VhbGl6ZWQgYmFzZWQgb24gZGVtb2NyYWN5IHNjb3JlICh4KQoKZ2dwbG90KGRhdGEgPSB3b3JsZCwgYWVzKHggPSBkZW1fc2NvcmUxNCwgeSA9IGdpbmkxMCkpICsgZ2VvbV9wb2ludCgpICAKCmdncGxvdChkYXRhID0gd29ybGQsIGFlcyh4ID0gZGVtX3Njb3JlMTQsIHkgPSBnaW5pMTAsIGNvbG9yID0gZ2RwX2NhcDMpKSArIGdlb21fcG9pbnQoKSAKCmdncGxvdChkYXRhID0gd29ybGQgLCBhZXMoeCA9IGRlbV9zY29yZTE0LCB5ID0gZ2luaTEwLCBjb2xvciA9IGdkcF9jYXAzKSkgKyBnZW9tX3BvaW50KCkgKyBmYWNldF93cmFwKH5yZWdpb251bikKCiMjIHVzaW5nIExhdHRpY2UgcGFja2FnZSAKeHlwbG90KGdpbmkxMH5kZW1fc2NvcmUxNCB8IHJlZ2ltZV90eXBlMyAsIGRhdGEgPSB3b3JsZCwgCiAgICAgICB0eXBlID0gImgiLCB4bGFiID0gIkRlbW9jcmFjeSBMZXZlbHMiKQoKCiMjIERpc2NyZXRlIHZhcmlhYmxlIChYKSBhbmQgRGlzY3JldGUgdmFyaWFibGUgKFkpLiBIZXJlIHJlZ2ltZSB0eXBlIGlzIHZpc3VhbGl6ZWQgd2l0aCBHRFAgcGVyIGNhcGl0YS4gCmdncGxvdChkYXRhID0gd29ybGQsIGFlcyh4ID0gZGVtX2xldmVsNCAsIHkgPSBnZHBfY2FwMywgY29sb3IgPSByZWdpbWVfdHlwZTMpKSArIGdlb21fY291bnQoKSAgCgpgYGAKCgojIyBSIENvZGUgZm9yIENvcnJlbGF0aW9uIFJlbGF0aW9uc2hpcHMKCmBgYHtyIENvcnJ2YXIsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyMuIENvcnJlbGF0aW9uIG9mIG51bWVyaWNhbCB2YXJpYWJsZXMKY29yciA9IGNvcihkaWFtb25kc1ssIGMoMSwgNTo3KV0pCmdnY29ycnBsb3QoY29yciA9IGNvcnIpCgojIyB1c2luZyBHR2FsbHkgcGFja2FnZS4gVGhlIEJ1c2ggYXBwcm92YWwgcmF0aW5ncyBpcyB1c2VkIHRvIHZpc3VhbGl6ZSB0aGUgcG9zc2libGUgY29ycmVsYXRpb25zLiAKZ2dwYWlycyhhcHByb3ZhbCwgY29sdW1ucyA9IDc6MTEsIGdncGxvdDI6OmFlcyhjb2xvcj1mYWN0b3IoWDExLlNlcCkpKQoKYGBgCgoKIyMuIFIgQ29kZSBmb3IgUmVncmVzc2lvbiBSZWxhdGlvbnNoaXBzCmBgYHtyIFJlZ3JlbCwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojI3VzaW5nIGdncGxvdCBwYWNrYWdlIGZvciByZWdyZXNzaW9uIGxpbmUgZml0CmdncGxvdChkYXRhID0gd29ybGQsIGFlcyh4ID0gZGVtX3Njb3JlMTQsIHkgPSBnaW5pMTAgKSkgKyBnZW9tX3BvaW50KG5hLnJtID0gVCkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBuYS5ybSA9IFQpICAKCiMjdXNpbmcgZ2dwbG90IHBhY2thZ2UgZm9yIHJlZ3Jlc3Npb24gbGluZSBmaXQgKGxvZXNzIG1ldGhvZCkKZ2dwbG90KGRhdGEgPSB3b3JsZCwgYWVzKHggPSBkZW1fc2NvcmUxNCwgeSA9IGdpbmkxMCkpICsgZ2VvbV9wb2ludChuYS5ybSA9IFQpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgbmEucm0gPSBUKSAKCiMjdXNpbmcgcXVhbnRpbGUgcmVncmVzc2lvbiBlc3RpbWF0aW9uCmdncGxvdChkYXRhID0gd29ybGQsIGFlcyh4ID0gZGVtX3Njb3JlMTQsIHkgPSBnaW5pMTApKSArZ2VvbV9wb2ludChuYS5ybSA9IFQpICsgZ2VvbV9xdWFudGlsZShuYS5ybSA9IFQpCgpgYGAKCiMjIFJlZ3Jlc3Npb24gZGlhZ25vc3RpY3MgdXNpbmcgZ2dwdWJyIGFuZCBnZ2ZvcnRpZnkgCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyMgVXNpbmcgZ2dwdWJyIHBhY2thZ2UKZ2dzY2F0dGVyKGRhdGEgPSB3b3JsZCwgeCA9ICJkZW1fc2NvcmUxNCIsIHkgPSAiZ2luaTEwIiwKICAgY29sb3IgPSAiYmxhY2siLCBzaGFwZSA9IDIxLCBzaXplID0gMywgIyBQb2ludHMgY29sb3IsIHNoYXBlIGFuZCBzaXplCiAgIGFkZCA9ICJyZWcubGluZSIsICAjIEFkZCByZWdyZXNzaW4gbGluZQogICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJsaWdodGdyYXkiKSwgIyBDdXN0b21pemUgcmVnLiBsaW5lCiAgIGNvbmYuaW50ID0gVFJVRSwgIyBBZGQgY29uZmlkZW5jZSBpbnRlcnZhbAogICBjb3IuY29lZiA9IFRSVUUsICMgQWRkIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50LiBzZWUgP3N0YXRfY29yCiAgIGNvci5jb2VmZi5hcmdzID0gbGlzdChtZXRob2QgPSAicGVhcnNvbiIsIGxhYmVsLnggPSAzLCBsYWJlbC5zZXAgPSAiXG4iKQogICApCgojI3VzaW5nIGdnZWZmZWN0cywgZ2dmb3J0aWZ5LCBhbmQgcGVyZm9ybWFuY2UgcGFja2FnZSB0byBlc3RpbWF0ZSBhbmQgZGlhZ25vc2l6ZSB0aGUgbGluZWFybW9kZWxzCiMjTW9kZWwuMTogcHJlZGljdGluZyBhbmQgZGlhZ29uaXppbmcgdGhlIGdlbmVyYWxpemVkIGxpbmVhciBtb2RlbAptMSA9IGxtKGFwcHJvdmV+Z2FzcHJpY2UgKyB1bmVtcGxveSArIGthdHJpbmEgKyBscmdhc3ByaWNlLCBkYXRhID0gYXBwcm92YWwpCmF1dG9wbG90KG0xLCB3aGljaCA9IDE6NiwgbmNvbCA9IDMsIGxhYmVsLnNpemUgPSAzKQoKCiMjTW9kZWwuMjogcHJlZGljdGluZyBhbmQgZGlhZ29uaXppbmcgdGhlIGdlbmVyYWxpemVkIGxpbmVhciBtb2RlbCB3aXRoIGFkZGl0aW9uIG9mIGlyYXEgaW52YXNpb24gdmFyaWFibGUKbTIgPSBsbShhcHByb3Zlfmdhc3ByaWNlICsgdW5lbXBsb3kgKyBrYXRyaW5hICsgbHJnYXNwcmljZSArIGlyYXFpbnZhZGUsIGRhdGEgPSBhcHByb3ZhbCkKYXV0b3Bsb3QobTIsIHdoaWNoID0gMTo2LCBuY29sID0gMywgbGFiZWwuc2l6ZSA9IDMpCgojI01vZGVsLjM6IHByZWRpY3RpbmcgYW5kIGRpYWdvbml6aW5nIHRoZSBnZW5lcmFsaXplZCBsaW5lYXIgbW9kZWwgd2l0aCBjb250cm9sIHZhcmlhYmxlcwptMyA9IGxtKGFwcHJvdmV+Z2FzcHJpY2UgKyB1bmVtcGxveSArIGthdHJpbmEgKyBscmdhc3ByaWNlICsgaXJhcWludmFkZSArIGxjcGlmb29kICsgWDExLlNlcCwgZGF0YSA9IGFwcHJvdmFsKQphdXRvcGxvdChtMywgd2hpY2ggPSAxOjYsIG5jb2wgPSAzLCBsYWJlbC5zaXplID0gMykKCiMjIENvZWZmaWNpZW50IGVzdGltYXRlcyBmb3IgdmFyaW91cyBtb2RlbHMKZzEgPSBnZ2NvZWYobTEsIHZsaW5lX2NvbG9yID0gImdyZWVuIiwgc29ydCA9ICJhc2NlbmRpbmciLCBleGNsdWRlX2ludGVyY2VwdCA9IFQpCmcyID0gZ2djb2VmKG0yLCB2bGluZV9jb2xvciA9ICJibHVlIiwgc29ydCA9ICJhc2NlbmRpbmciLCBleGNsdWRlX2ludGVyY2VwdCA9IFQpCmczID0gZ2djb2VmKG0zLCB2bGluZV9jb2xvciA9ICJyZWQiLCBzb3J0ID0gImFzY2VuZGluZyIsIGV4Y2x1ZGVfaW50ZXJjZXB0ID0gVCkKCmdyaWQuYXJyYW5nZShnMSwgZzIsIGczLCBucm93PTMpCmBgYAoKCgo=